In [1]:
import os
import pickle
import numpy as np
import pandas as pd
from utils_res import return_dict, bad_scores, accuracy_plot, accuracy, check_selectivity, get_len, common_neurons, common_neurons_percentage, get_bottom, Init, common_neurons_percentage_multiple, common_neurons_multiple

Загружаем метрики и ранжирование нейронов¶

In [2]:
path = os.path.abspath('../')+'/results/kenet/'
kenet = Init(path, 'tr', 'kenet')
In [3]:
with open(f'{path}weights_tr_kenet.pkl', 'rb') as f:
            weights = return_dict(pickle.load(f), 'tr')
In [4]:
path = os.path.abspath('../')+'/results/gum/'
gum = Init(path, 'en', 'gum')
In [5]:
with open(f'{path}weights_en_gum.pkl', 'rb') as f:
    weights_gum = return_dict(pickle.load(f), 'en')
In [6]:
path = os.path.abspath('../')+'/results/gum2/'
gum2 = Init(path, 'en', 'gum')
In [7]:
path = os.path.abspath('../')+'/results/gsd/'
gsd = Init(path, 'de', 'gsd')
In [8]:
with open(f'{path}weights_de_gsd.pkl', 'rb') as f:
    weights_gsd = return_dict(pickle.load(f), 'de')

Тут: 2 эксперимента на одном и том же англ. датасете¶

In [9]:
accuracy_plot(gum.scores, gum.size)

Сбой при повторении эксперимента¶

In [10]:
accuracy_plot(gum2.scores, gum2.size)

Control Task¶

1 эксперимент¶

In [11]:
selectivity = check_selectivity(gum.scores) - check_selectivity(gum.scores_c)
#'Selectivity (Diff. between true task and control task performance)
dict(zip(list(gum.scores.keys()), selectivity))
Out[11]:
{'Definite': 0.23964868255959848,
 'Case': 0.4461805555555555,
 'Gender': 0.3830227743271221,
 'Number': 0.34013605442176875,
 'Degree': 0.12668463611859837,
 'PronType': 0.5508982035928143,
 'NumType': 0.523961661341853,
 'Person': 0.49130938586326767,
 'VerbForm': 0.32861189801699714,
 'Mood': 0.17391304347826086,
 'Tense': 0.33111111111111113}

2 эксперимент¶

In [12]:
selectivity = check_selectivity(gum2.scores) - check_selectivity(gum2.scores_c)
#'Selectivity (Diff. between true task and control task performance)
dict(zip(list(gum2.scores.keys()), selectivity))
Out[12]:
{'Definite': 0.22333751568381432,
 'Case': -0.4097222222222222,
 'Gender': 0.4927536231884058,
 'Number': 0.3412698412698412,
 'Degree': 0.09703504043126687,
 'PronType': 0.5009980039920159,
 'NumType': 0.2747603833865815,
 'Person': 0.5260718424101969,
 'VerbForm': 0.3980169971671388,
 'Mood': 0.75,
 'Tense': 0.30444444444444446}

Топ и боттом нейроны¶

Про ранжирование нейронов¶

Раньше -- просто смотрела на N нейронов.

Improved -- смотреть на основе весов. Можно смотреть топ-10% нейронов. А можно топ-1%. А можно топ-30%. Отсечки идут с шагом 1. Но то, что входит в топ-1, например нейрон #2, #9654, #700 -- попадают в chunk без ранжирования.

Как это может выглядеть:

  • top-1% по весу: 2 нейрона,
  • top-2% по весу: 11 нейронов (2+9),
  • top-3% по весу: 19 нейронов, и т.д. -- 32, 45, 62, 77, 92, 109, 131

Другой метод: на основе определенного theshold'а.

neurons with weight > threshold * max_weight -- top neurons (мой трешхолд 0.5).

Top 10%¶

Чтобы сократить количество графиков, просто посмотрим на разницу скора на всех нейронах и на топ-10.

In [13]:
selectivity = check_selectivity(gum.scores) - check_selectivity(gum.scores_keep_top)
dict(zip(list(gum.scores.keys()), selectivity))
Out[13]:
{'Definite': -0.0025094102885822034,
 'Case': -0.02256944444444453,
 'Gender': 0.039337474120082816,
 'Number': 0.043083900226757454,
 'Degree': -0.02964959568733161,
 'PronType': -0.05189620758483038,
 'NumType': -0.03194888178913746,
 'Person': 0.009269988412514474,
 'VerbForm': -0.016997167138810165,
 'Mood': 0.005434782608695676,
 'Tense': 0.0}

ВЫВОД: на топ кое-где метрики выше --> возможно, меньше переобучается.

Control task на топ-нейронах:

In [14]:
selectivity = check_selectivity(gum.scores_keep_top) - check_selectivity(gum.scores_keep_top_c)
dict(zip(list(gum.scores.keys()), selectivity))
Out[14]:
{'Definite': 0.25972396486825594,
 'Case': 0.31423611111111116,
 'Gender': 0.3643892339544513,
 'Number': 0.28344671201814053,
 'Degree': 0.0,
 'PronType': 0.5788423153692615,
 'NumType': 0.6038338658146966,
 'Person': 0.5272305909617613,
 'VerbForm': 0.3498583569405099,
 'Mood': 0.2192028985507246,
 'Tense': 0.2844444444444445}

ВЫВОД: у каких-то категорий селективность на топ-нейронах выше, чем на всех, но не везде.

Сколько вообще нейронов попадают в топ-10 %¶

In [15]:
get_len(gum.top_neurons)

ВЫВОД: чем больше меток у категории, тем больше нейронов нужно.

По методу трешхолда: где-то больше нейронов, где то меньше.

In [16]:
get_len(gum.ordered_neurons_thres)

Результаты на топ-10 и на трешхолд +- сравнимы. На трешхолде даже получше.

In [17]:
selectivity = check_selectivity(gum.scores_keep_top) - check_selectivity(gum.scores_keep_thres)
dict(zip(list(gum.scores.keys()), selectivity))
Out[17]:
{'Definite': -0.016311166875784155,
 'Case': -0.00694444444444442,
 'Gender': 0.01863354037267073,
 'Number': 0.041950113378684706,
 'Degree': -0.005390835579514808,
 'PronType': -0.003992015968063867,
 'NumType': -0.006389776357827448,
 'Person': 0.035921205098493614,
 'VerbForm': -0.004249291784702569,
 'Mood': -0.0018115942028985588,
 'Tense': -0.0022222222222222365}

Пересечение топ-10 и метода треш холда.

In [18]:
common_neurons(gum.top_neurons, gum.ordered_neurons_thres)
Out[18]:
Definite Case Gender Number Degree PronType NumType Person VerbForm Mood Tense
0 207 375 120 107 285 805 449 126 446 128 162
In [19]:
common_neurons_percentage(gum.top_neurons, gum.ordered_neurons_thres) # в процентном соотношении
Out[19]:
Definite Case Gender Number Degree PronType NumType Person VerbForm Mood Tense
0 63.11 82.78 42.7 55.44 67.38 77.11 58.77 55.26 95.1 88.28 84.38

Интересное о bottom-нейронах¶

In [20]:
gum_bot_neurons = get_bottom(gum.ordered_neurons, gum.bottom_neurons)
gum_bot_neurons2 = get_bottom(gum.ordered_neurons, gum.bottom_neurons2)

Вот столько попадает в bottom 10%

In [21]:
get_len(gum_bot_neurons)

Вот столько попадает в bottom 2%

In [22]:
get_len(gum_bot_neurons2)

Где-то мы видим очень много нейронов даже в 2% отсечке с конца. -> категории, у которых больше меток в категории наверняка более распределены по НС?

Вот тут скор на 2% нейронов. Где-то вполне высокий. Почему? Потому что туда попало много нейронов, и в них тоже какая то информация содержится?

In [23]:
accuracy(gum.scores_keep_bot2)

Но не так хорошо, как если мы будем выбирать нейроны на основе их веса (тут по методу трешхолда).

In [24]:
accuracy(gum.scores_keep_thres)

Печальные результаты¶

По каким-то причинам эксперимент не является устойчиво воспроизводимым и консистентным.

100 % каждый раз я подаю одни и те же данные, 100 % эмбеддинги предложений одинаковы.

Топ-10 % нейронов по весу не вполне приятно пересекается.

In [25]:
common_neurons_percentage(gum.top_neurons, gum2.top_neurons)
Out[25]:
Definite Case Gender Number Degree PronType NumType Person VerbForm Mood Tense
0 41.92 35.58 47.15 70.69 34.71 30.63 37.52 35.01 44.69 62.18 70.83

Посмотрим на то, как выглядят веса для простой категории Definite, которая не должна быть слишком распределенной, поскольку в топ-10 нейронов попало их 207 штук в 1 эксперименте и 206 во втором.

In [26]:
sorted(weights_gum['Definite'][1][0])[::-1][:10] 
Out[26]:
[0.07864328,
 0.076466165,
 0.07473722,
 0.070885286,
 0.0708754,
 0.070468225,
 0.07042361,
 0.06941098,
 0.06885049,
 0.06797053]
In [27]:
sorted(weights_gum['Definite'][1][0])[::-1][100:120] 
Out[27]:
[0.04797148,
 0.04795572,
 0.047868367,
 0.047736432,
 0.04758441,
 0.047581255,
 0.047454085,
 0.047387626,
 0.047183324,
 0.047093723,
 0.047066495,
 0.04689828,
 0.04674845,
 0.046747047,
 0.046585783,
 0.046541803,
 0.046494827,
 0.046489473,
 0.046468757,
 0.046440605]

Веса маленькие и какие то погрешности получаются? Не знаю, как оценить

In [28]:
common_neurons_percentage_multiple(gum.ordered_neurons, gum2.ordered_neurons)
Out[28]:
Definite Case Gender Number Degree PronType NumType Person VerbForm Mood Tense
5% 35.24 29.15 37.96 67.90 27.03 24.84 29.89 35.54 39.74 46.03 53.16
10% 42.15 33.84 45.78 67.45 32.91 29.39 37.05 35.22 43.50 58.74 73.96
20% 38.96 41.03 46.54 67.64 39.87 41.21 40.92 38.98 46.49 62.89 68.67
30% 42.93 45.85 49.46 71.10 44.98 49.04 45.77 45.70 50.32 67.23 71.73
40% 44.63 49.21 53.92 71.87 49.64 54.72 50.93 49.53 53.83 68.26 71.58
50% 46.31 53.14 54.76 74.49 53.51 60.88 55.51 52.25 58.55 70.23 73.81
75% 54.52 64.53 63.20 78.10 62.39 79.19 67.29 60.26 69.56 73.58 77.55
80% 55.62 66.56 65.33 80.49 64.57 84.08 70.37 63.10 72.84 75.56 77.71
90% 58.50 73.18 70.86 83.44 72.59 95.06 78.74 66.00 81.49 81.31 81.44
99% 71.93 93.72 92.52 88.66 93.58 99.99 98.37 94.21 98.54 88.31 89.78

Вывод?

Версии

  • Метка для слова, а смотрим на эмбеддинг предложения
  • Плохие данные? Мало данных?
  • Правда ничего особо качественного не учится

Что делать дальше:

  • в этой части, наверное, можно каким-то образом выбирать наименьшие chunk'и нейронов, выделенных на основе разных экспериментов, разных методов. Это подобие нахождения minimal neural set, но надо понять, какую погрешность на скоре мы могли бы себе позволить? Стоит ли вообще это делать? (эксперимент ниже с турецким BERT).

  • перейти к другим видам пробинга?

Эксперимент с турецким БЕРТом (для экзотики)¶

Kenet dataset¶

In [29]:
accuracy_plot(kenet.scores, kenet.size)

Тут все плохо даже без Control Task.

In [30]:
get_len(kenet.top_neurons)
In [31]:
sorted(weights['Definite'][1][0])[::-1][:10] 
Out[31]:
[0.10430164,
 0.09602796,
 0.08893047,
 0.088621564,
 0.083882816,
 0.08374987,
 0.08006921,
 0.07876948,
 0.07842627,
 0.07724879]

На топ-10% нейронов также все крайне печально по пересечению с экспериментами на английском BERT'е на GUM датасете.

In [32]:
common_neurons_percentage(kenet.top_neurons, gum.top_neurons)
Out[32]:
Definite Case Number Degree PronType NumType Person VerbForm Mood Tense
0 0.26 2.32 1.13 2.27 4.1 0.78 2.82 4.15 2.22 1.57

German BERT¶

In [33]:
accuracy_plot(gsd.scores, gsd.size)
In [34]:
selectivity = check_selectivity(gsd.scores) - check_selectivity(gsd.scores_c)
#'Selectivity (Diff. between true task and control task performance)
dict(zip(list(gsd.scores.keys()), selectivity))
Out[34]:
{'Definite': 0.1900311526479751,
 'Case': 0.5035971223021583,
 'Gender': 0.3,
 'Number': 0.35315533980582514,
 'Degree': 0.28961748633879786,
 'PronType': 0.4835589941972921,
 'NumType': 0.25688073394495414,
 'Person': 0.34098939929328625,
 'VerbForm': 0.3198031980319804,
 'Mood': 0.005050505050504972,
 'Tense': 0.2733333333333333}
In [35]:
common_neurons_multiple(gum.ordered_neurons, gsd.ordered_neurons) #англ.и нем.
Out[35]:
Definite Case Gender Number Degree PronType NumType Person VerbForm Mood Tense
5% 3 0 1 0 5 9 5 2 2 0 0
10% 9 17 14 2 26 62 16 4 21 5 2
20% 25 92 79 13 123 337 59 29 92 33 8
30% 69 254 221 48 290 853 160 91 260 80 38
40% 149 542 450 104 553 1686 319 218 514 172 79
50% 270 984 776 187 973 2755 600 455 924 348 162
75% 1044 3020 2476 779 2887 6889 2045 1969 2848 1389 670
80% 1369 3682 3022 1033 3622 7804 2574 2592 3502 1865 866
90% 2475 5815 4929 2125 5575 9465 4124 5123 5561 3653 1894
99% 6637 9582 9369 6572 9377 9984 8209 9511 9517 8075 6352
In [36]:
common_neurons_percentage_multiple(gum.ordered_neurons, gsd.ordered_neurons) #англ.и нем. в процентах
Out[36]:
Definite Case Gender Number Degree PronType NumType Person VerbForm Mood Tense
5% 2.24 0.00 0.41 0.00 1.61 1.50 1.98 1.31 0.69 0.00 0.00
10% 2.44 2.15 2.30 0.64 3.45 4.31 2.60 0.97 3.00 1.13 0.80
20% 2.82 5.03 5.37 1.68 7.09 10.66 4.08 2.86 5.48 3.21 1.18
30% 4.65 8.60 9.19 3.70 10.50 17.73 6.72 5.26 9.53 4.58 3.38
40% 6.92 13.19 13.22 5.59 14.38 26.80 9.37 8.31 13.50 6.69 4.83
50% 9.31 18.75 17.33 7.38 19.74 36.13 13.55 12.22 19.00 9.82 7.21
75% 20.02 37.87 34.32 16.39 37.20 71.62 28.39 28.57 37.80 20.53 15.57
80% 23.60 43.42 38.68 19.22 43.66 79.55 33.17 34.20 43.10 24.87 17.62
90% 33.91 61.78 54.25 30.18 60.03 94.88 45.98 55.87 59.53 40.57 28.54
99% 68.94 96.03 93.94 68.47 94.00 100.00 82.35 95.31 95.34 81.14 66.42
In [37]:
common_neurons_percentage_multiple(gum.ordered_neurons, kenet.ordered_neurons) #англ.и турецкий
Out[37]:
Definite Case Number Degree PronType NumType Person VerbForm Mood Tense
5% 0.00 0.67 0.00 1.13 1.38 0.00 2.07 2.51 0.74 1.08
10% 0.29 2.12 1.28 1.78 3.68 0.72 2.55 3.86 2.26 1.55
20% 1.68 5.97 0.89 5.56 8.41 3.36 4.61 5.66 3.11 3.73
30% 3.35 10.80 3.05 8.86 15.24 6.19 6.97 9.83 5.14 4.51
40% 5.00 16.29 5.06 12.28 23.55 10.43 9.85 14.09 6.88 7.24
50% 7.29 22.16 7.22 16.45 32.99 15.00 13.61 19.45 9.58 10.16
75% 16.99 44.18 15.99 33.53 68.21 31.34 26.55 38.52 21.65 21.28
80% 20.39 50.16 19.08 39.21 76.72 36.51 31.48 45.32 26.85 24.98
90% 30.10 67.65 29.43 55.57 93.70 51.81 50.11 67.03 44.16 37.68
99% 66.75 96.63 67.71 91.29 100.00 94.33 93.51 98.58 82.00 77.16
In [38]:
common_neurons_percentage_multiple(gsd.ordered_neurons, kenet.ordered_neurons) #турецкий и немецкий
Out[38]:
Definite Case Number Degree PronType NumType Person VerbForm Mood Tense
5% 0.00 0.82 0.00 1.34 1.70 0.00 0.00 1.07 1.45 0.00
10% 0.57 3.35 0.00 1.62 4.08 0.00 1.54 2.51 3.15 0.48
20% 1.70 7.48 1.66 4.57 9.58 2.12 2.65 5.42 7.19 2.25
30% 3.66 12.53 4.39 8.00 16.69 3.63 5.38 8.77 12.10 3.92
40% 5.47 19.25 6.49 11.80 24.32 6.80 8.93 12.46 17.94 5.66
50% 7.43 27.04 8.64 16.92 34.95 10.14 13.86 17.06 25.84 8.22
75% 16.87 53.07 16.63 36.12 70.15 22.90 31.84 34.56 54.66 17.98
80% 20.09 59.72 19.52 42.21 78.66 27.13 37.25 39.70 62.74 21.48
90% 29.84 78.92 29.18 59.52 94.54 38.71 55.91 58.05 80.75 35.00
99% 68.12 99.28 67.09 92.49 100.00 79.37 94.44 95.42 98.56 77.69